#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <cstring>
#include <unistd.h>
using namespace std;

//重定向原理：
//文件描述符的分配原则：最小的、没有使用的，作为新的fd分配给用户

int main()
{

    printf("stdout:%d\n", stdout->_fileno);
    printf("stdin:%d\n", stdin->_fileno);
    printf("stderr:%d\n", stderr->_fileno);
    umask(0);
    //int fd = open("log.txt", O_CREAT|O_WRONLY|O_APPEND, 0666);
    //0，1，2表示标准输入、标准输出、标准错误
    //FILE是C语言提供的一个结构体，是typedef XXX（。。。）FILE
    //在操作系统层面，只认fd，即文件描述符
    //
    //
    //系统会创建一个struct file，其中有int mode, 读写位置，读写选项，缓冲区
    //操作方法，struct file* next; struct file就代表被打开的文件
    //
    //
    //O_TRUNC，清空目标文件并写入
    int fd = open("test.txt", O_RDONLY);
   // close(1);
    //int fd = open("log.txt", O_CREAT|O_WRONLY|O_APPEND, 0666);
   // printf("%d\n", fd);
   // close(1);
    //printf就是往stdout打的，但是这里stdout已经被关闭，替代他的是log.txt的文件
    //标识符，所以printf就往log.txt输出了，形成了重定向的“假象”
    //所谓重定向，就是改变文件描述符表的指针指向，数组下表不变
    //
    //重定向：打开文件的方式 + dup2
    //
    //int dup2(int oldfd, int newfd)
    
    int ret = dup2(fd, 0);
    while(1)
    {
        char buffer[64];
        if(!fgets(buffer, sizeof(buffer), stdin)) break;

        printf("%s", buffer);
    }
    //
    //if(fd < 0)
    //{
    //    perror("open");
    //    return 1;
    //}

    //const char* msg = "Hello Linux\n";
    //int cnt = 5;

    //int a = 123456;
    //while(cnt--)
    //{
    //    char buffer[16];
    //    snprintf(buffer, sizeof(buffer), "%d", a);
    //    write(fd, buffer, strlen(buffer));
    //}

    //while(1)
    //{
    //    char buffer[128];
    //    int n = read(fd, buffer, sizeof(buffer) - 1);
    //    if(n > 0)
    //    {
    //        buffer[n] = 0;
    //        printf("%s", buffer);
    //    }
    //    else if(n == 0)
    //    {
    //        break;
    //    }
    //}
    //printf("fd:%d", fd);
    //close(fd);
    return 0;
}








//int main()
//{
//    printf("hello world\n");
//    fprintf(stdout, "Hello fprintf\n");
//    const char* msg = "Hello fwrite\n";
//    fwrite(msg, strlen(msg), 1, stdout);
//    //三个文件输入输出流：stdout、stderr、stdin（FILE*）
//    //                显示器文件 标准错误 键盘文件
//    //                标准输出 显示器文件 标准输入
//    FILE* fp = fopen("test.cpp", "a");//a是append方式，追加
//    fprintf(fp, "%s", msg);
//    //只要在文件中写字符串，就不要写\0，写了就是乱码，因为这是C语言的
//    //规定，和文件的读写没关系
//    
//    return 0;
//}


//int main()
//{
//    FILE* file = fopen("test.cpp", "w");
//    if(file == nullptr)
//    {
//        perror("fopen");
//        return 1;
//    }
//
//    const char* msg = "Hello Linux:";
//    int cnt = 1;
//    while(cnt <= 10)
//    {
//        char buffer[1024];
//        snprintf(buffer, sizeof(buffer), "%s %d\n", msg, cnt++);
//
//        fwrite(buffer, strlen(buffer), 1, file);
//    }
//    fclose(file);
//    return 0;
//}
